package com.qf.service.impl;

import com.qf.constant.CacheConstants;
import com.qf.constant.StrategyConstants;
import com.qf.feign.CacheFeign;
import com.qf.model.StandardSubmit;
import com.qf.service.FilerChainService;
import com.qf.util.PushMsgUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Map;

/**
 * projectName: sms-platform02
 *
 * @author: 元
 * time: 2021/10/18 0018 16:57
 * description:扣费策略实现类
 * 发送目标手机号运营商不同,费用不同
 */
@Slf4j
@Service(value = "fee")
public class FeeServiceImpl implements FilerChainService{

    @Autowired
    private CacheFeign cacheFeign;
    @Autowired
    private PushMsgUtil pushMsgUtil;



    @Override
    public boolean strategy(StandardSubmit standardSubmit) {
        log.info("[策略模块-扣费策略],开始执行,standardSubmit={}",standardSubmit);
        //1.先查询当前账户的余额
        Map clientMap = cacheFeign.hMGet(CacheConstants.CACHE_PREFIX_CLIENT + standardSubmit.getClientID());
        if (clientMap == null){
            log.info("[策略模块~扣费策略],该用户账户信息无法读取,standardSubmit={}",standardSubmit);
            return false;
        }
        Object feeObj = clientMap.get("fee");
        if (StringUtils.isEmpty(feeObj)){
            log.info("[策略模块~扣费策略],该用户账户信息无法读取,standardSubmit={}",standardSubmit);
            return false;
        }
            //账户余额
        long totalFee = Long.parseLong(String.valueOf(feeObj));

        //2.查询当前短信锁需要的费用
        Long fee = standardSubmit.getFee();

        //3.判断用户剩余费用是否足够发送短信
        if(totalFee >= fee){
            //4.如满足要求,则进行扣费
           totalFee = cacheFeign.hincr(CacheConstants.CACHE_PREFIX_CLIENT + standardSubmit.getClientID(),"fee",-fee);
            //5.判断扣费完成后,用户剩余的金额需要>0
            if (totalFee < 0){
                //6.如果扣除后余额<0,则提示用户账号资金不足,将扣除的费用加回该用户账户,发送失败,则记录发送日志
                //短信发送失败后,记录发送日志

                //推送发送短信失败的消息到MQ中,然后接口模块再将这个数据接收后返回给用户
                pushMsgUtil.pushReport(standardSubmit, StrategyConstants.STRATEGY_ERROR_FEE);
                //记录发送失败的日志,通过MQ和Search模块将数据存入ES服务器中,以便客户管理员在可视化界面查询使用
                pushMsgUtil.pushReport(standardSubmit,StrategyConstants.STRATEGY_ERROR_FEE);
                log.info("[策略模块-扣费策略],扣费失败,余额不足,standardSubmit={}",standardSubmit);
                return true;
            }
        //7.若成功发送,计算客户余额到redis中
        cacheFeign.incr(CacheConstants.CACHE_PREFIX_CUSTOMER_FEE + standardSubmit.getClientID(),fee);

        log.info("[策略模块-扣费策略],扣费成功,standardSubmit={}",standardSubmit);
        return true;
    }else {
        //推送发送短信失败的消息到MQ中,然后接口模块再将这个数据接收后返回给用户
        pushMsgUtil.pushReport(standardSubmit, StrategyConstants.STRATEGY_ERROR_FEE);
        //记录发送失败的日志,通过MQ和Search模块将数据存入ES服务器中,以便客户管理员在可视化界面查询使用
        pushMsgUtil.pushReport(standardSubmit,StrategyConstants.STRATEGY_ERROR_FEE);
        log.info("[策略模块-扣费策略],扣费失败,该账户余额不足,standardSubmit={}",standardSubmit);
        return false;
        }
}
}